package com.drakulo.hi.logic.battle;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.drakulo.hi.states.BattleState;

/**
 * The battle line is the play order of all actors in a battle. Order is defined initiative of each
 * actors
 */
public class BattleLine {
	/**
	 * The battle line
	 */
	BattleActor[] battleActors;

	/**
	 * The index in the battle line of the head actor
	 */
	private int headIndex;

	/**
	 * Constructor
	 * 
	 * @param actorList
	 *            - the battle actors
	 */
	public BattleLine(List<BattleActor> actorList) {
		this.headIndex = 0;
		this.battleActors = new BattleActor[actorList.size()];

		// The actor list is sorted by initiative
		Comparator<BattleActor> comp = new Comparator<BattleActor>() {
			public int compare(BattleActor b1, BattleActor b2) {
				return b1.getInitiative().compareTo(b2.getInitiative());
			}
		};
		Collections.sort(actorList, comp);

		// Initialization of the BattleLine
		int index = 0;
		for (BattleActor actor : actorList) {
			this.battleActors[index] = actor;
			index++;
		}
	}

	/**
	 * Ends a battle turn
	 */
	public void endTurn() {
		if (this.headIndex + 1 == this.battleActors.length) {
			// We're at the end of the battle line. Go back to start
			this.headIndex = 0;
		} else {
			// The head of the battle line increase
			this.headIndex++;
		}
	}

	/**
	 * @return the status of the battle : won, in progress or lost
	 */
	public int getBattleStatus() {
		int enemies = 0;
		int allies = 0;
		for (BattleActor actor : this.battleActors) {
			if (actor.isAlive()) {
				if (actor.isAlly()) {
					allies++;
				} else {
					enemies++;
				}
			}
		}

		if (enemies > 0 && allies > 0) {
			// There is a least 1 ally and 1 enemy, the show must go on!
			return BattleState.IN_PROGRESS;
		}

		if (enemies == 0) {
			// No more enemies : victory for the player
			return BattleState.VICTORY;
		} else {
			// The player loose the battle :(
			return BattleState.DEFEAT;
		}
	}

	/**
	 * Creates a list with actors ordered by their actual position in the battle line
	 * 
	 * @return - a list
	 */
	public List<BattleActor> getCurrentDisplay() {
		List<BattleActor> actors = new ArrayList<BattleActor>();
		// The iterations must not modify the current head index
		int actorsHandled = 0;
		int index = this.headIndex;
		while (actorsHandled != this.battleActors.length) {
			actors.add(this.battleActors[index]);

			// One more actor was handled
			actorsHandled++;

			if (index + 1 != this.battleActors.length) {
				index++;
			} else {
				// We reached the end of the battle line, so we go back to start
				index = 0;
			}
		}
		return actors;
	}

	/**
	 * @return the actor currently on the head of the battle line
	 */
	public BattleActor getHeadActor() {
		return this.battleActors[this.headIndex];
	}
}
